/*
 * ProtocolCan2Eth.h
 *
 *  Created on: Dec 8, 2011
 *      Author: kylintse
 */

#ifndef PROTOCOLCAN2ETH_H_
#define PROTOCOLCAN2ETH_H_
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>

#include <linux/can.h>
#include <linux/can/raw.h>

#include <string.h>

#include "DeviceProtocol.h"
#include "kthread.h"

class ProtocolCan2Eth;

class Can2EthRecver : public kthread
{
public:
	Can2EthRecver(ProtocolCan2Eth* protocol,QObject* parent=0);
	~Can2EthRecver();

protected:
	virtual void run();

private:
	ProtocolCan2Eth* m_protocol;
};

class Can2EthSender : public kthread
{
public:
	Can2EthSender(ProtocolCan2Eth* protocol,KjDeviceList* lstDevice,
			QObject* parent=0);
	~Can2EthSender();

protected:
	virtual void run();

private:
	ProtocolCan2Eth* m_protocol;
	KjDeviceList* m_lstDevice;
};

typedef struct _tCan2EthFrame
{
	quint8 canFrameWant;
	quint8 canFrameGet;
	quint8 autoSend;
	quint8 canAddr;
	quint32 dataLen;
	QDateTime timeEn;
	char* data;
}Can2EthFrame;

typedef struct _tCan2EthCmdSource
{
	quint8 notifyFinish;
	QString source;
	quint32 devId;
	QDateTime timeEn;
}Can2EthCmdSource;

class ProtocolCan2Eth : public DeviceProtocol
{
public:
	ProtocolCan2Eth(quint32 id,const QString& devNode,KjDeviceList* lstDevice);
	virtual ~ProtocolCan2Eth();

public:
	virtual bool start();
	virtual void stop();

	void processRecv();

	void processCommand();

	bool putCanFrameAutoSend(quint8 canFrameNum,quint32 ethCount,quint8 canAddr,
			char* data,quint8 dataLen);

	bool putCanFrameInteract(quint8 canFrameNum,quint32 ethCount,quint8 canAddr,
				char* data,quint8 dataLen);

	bool putCommandSource(quint32 ethCount,const QString& source,quint32 devId);

	virtual void recycle();

private:
	int m_sockfd;

	QMutex m_lockFrameAutoSend;
	QMap<quint32,Can2EthFrame*> m_framesAutoSend;

	QMutex m_lockFrameInteract;
	QMap<quint32,Can2EthFrame*> m_framesInteract;
	QMap<quint32,Can2EthCmdSource*> m_cmdSources;

	Can2EthRecver* m_recver;
	Can2EthSender* m_sender;
	DeviceProtocolRecycler* m_recycler;

	struct can_frame m_curCanFrmRecv;
	struct can_frame m_curCanFrmSend;

	quint32 m_curEthCount;
};

#endif /* PROTOCOLCAN2ETH_H_ */
